package com.example.sourcecodelearning.spring.factory;

import com.example.sourcecodelearning.spring.resource.BeanDefinition;
import com.example.sourcecodelearning.spring.resource.ResourceLoader;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.util.Map;

/**
 * Bean工厂，负责创建bean
 */
@Slf4j
public class BeanFactory {

    private final Map<String, BeanDefinition> beanDefinationMap;

    private final BeanRegister beanRegister;

    public BeanFactory() {
        // 1. 获取BeanName-BeanClass的映射Map
        beanDefinationMap = ResourceLoader.getResource();
        System.out.println("获取资源成功");
        beanRegister = new BeanRegister();
        System.out.println("创建bean注册器成功");
    }

    public Object getBean(String beanName) {
        // 先从bean容器获取
        Object bean;
        bean = beanRegister.getSingletonBean(beanName);
        if (bean != null) {
            System.out.println("从bean容器获取【" + beanName + "】");
            return bean;
        }
        // 没有再创建并注册到容器中
        bean = createBean(beanDefinationMap.get(beanName));
        Assert.notNull(bean, "没有【" + beanName + "】这个bean");
        return bean;
    }

    private Object createBean(BeanDefinition beanDefinition) {
        if (beanDefinition == null) {
            return null;
        }
        try {
            // 反射创建bean
            Object bean = beanDefinition.getBeanClass().getDeclaredConstructor().newInstance();
            // 注册到bean容器中
            beanRegister.registerSingletonBean(beanDefinition.getBeanName(), bean);
            System.out.println("通过反射创建bean【" + beanDefinition.getBeanName() + "】");
            return bean;
        } catch (Exception e) {
            log.error("通过反射创建bean失败，e:{}", e.getMessage());
        }
        return null;
    }
}
